/**  
 * Copyright (c) 2008, Noel Lynch All rights reserved. Redistribution and use  
 * in source and binary forms, with or without modification, are permitted  
 * provided that the following conditions are met: Redistributions of source  
 * code must retain the above copyright notice, this list of conditions and the  
 * following disclaimer. Redistributions in binary form must reproduce the above  
 * copyright notice, this list of conditions and the following disclaimer in the  
 * documentation and/or other materials provided with the distribution. Neither  
 * the name of Noel Lynch nor the names of contributors may be used to  
 * endorse or promote products derived from this software without specific prior  
 * written permission. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND 
 * CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT  
 * NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A  
 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR  
 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,  
 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,  
 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;  
 * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,  
 * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR  
 * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF  
 * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.  
 */
// Nov 24, 2008

package com.sceneworker.editors.trimesheditor;

import java.awt.Dimension;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import java.io.File;
import java.io.IOException;
import java.nio.FloatBuffer;
import java.nio.IntBuffer;

import javax.swing.JButton;
import javax.swing.JCheckBox;
import javax.swing.JDialog;
import javax.swing.JLabel;
import javax.swing.JPanel;

import com.jme.math.Quaternion;
import com.jme.math.Vector3f;
import com.jme.scene.TriMesh;
import com.jme.util.export.binary.BinaryExporter;
import com.jme.util.geom.BufferUtils;
import com.myjavautils.GenericUtils;
import com.myjavautils.swing.MigLayoutUtils;
import com.myjavautils.swing.SimpleAlert;
import com.myjavautils.swing.SwingComponentFactory;

public class ExportTriMeshPanel extends JPanel {

	private		JDialog		mcl_parent;
	private		TriMesh		mcl_mesh;
	private		JCheckBox	mcl_normalsCBox;
	private		JCheckBox	mcl_coloursCBox;
	private		JCheckBox	mcl_textureCoordsCBox;
	private		JCheckBox	mcl_worldTXCBox;

	private		File		mcl_saveToLocation;

	public ExportTriMeshPanel(JDialog cl_par, TriMesh cl_mesh) {
		mcl_parent = cl_par;
		mcl_mesh = cl_mesh;

		initUI();
	}

	protected	void	initUI() {
		MigLayoutUtils.asMigLayout(this);

		if(mcl_mesh.getNormalBuffer() != null) {
			mcl_normalsCBox = SwingComponentFactory.makeACheckBox("Export Normals", true);
			add(mcl_normalsCBox, "wrap");
		}

		if(mcl_mesh.getTextureCoords() != null) {
			if(mcl_mesh.getTextureCoords().size() > 0) {
				mcl_textureCoordsCBox = SwingComponentFactory.makeACheckBox("Export Texture Coords", true);
				add(mcl_textureCoordsCBox, "wrap");
			}
		}

		if(mcl_mesh.getColorBuffer() != null) {
			mcl_coloursCBox = SwingComponentFactory.makeACheckBox("Export Colours", true);
			add(mcl_coloursCBox, "wrap");
		}

		mcl_worldTXCBox = SwingComponentFactory.makeACheckBox("Export with world transformations applied", true);
		add(mcl_worldTXCBox, "wrap");
		
		final	JLabel		lcl_savetoLbl = new JLabel();
		lcl_savetoLbl.setPreferredSize(new Dimension(150, 30));
		JButton			lcl_saveToBtn = SwingComponentFactory.makeAButton("Save TriMesh To");
		lcl_saveToBtn.addActionListener(new ActionListener() {

			public void actionPerformed(ActionEvent arg0) {
				File		lcl_file = GenericUtils.getAFile(mcl_worldTXCBox, false, true);
				mcl_saveToLocation = lcl_file;
				lcl_savetoLbl.setText(mcl_saveToLocation.getName());
			}

		});
		
		add(lcl_saveToBtn);
		add(lcl_savetoLbl, "wrap");

		JButton		lcl_cancel = SwingComponentFactory.makeAButton("Cancel");
		lcl_cancel.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent arg0) {
				mcl_parent.setVisible(false);
			}

		});
		
		JButton		lcl_save = SwingComponentFactory.makeAButton("Save");
		lcl_save.addActionListener(new ActionListener() {
			public void actionPerformed(ActionEvent e) {

				if(mcl_saveToLocation == null) {
					SimpleAlert.doAlert("You have not selected where to save the mesh.", mcl_parent);
					return;
				}

				exportTriMesh();

				mcl_parent.setVisible(false);
			}

		});
		
		MigLayoutUtils.makeRightAlignedButtonBar(this, lcl_cancel, lcl_save);

	}

	protected	void	exportTriMesh() {
		TriMesh		lcl_newTM = new TriMesh(mcl_mesh.getName() + " copy");

		FloatBuffer		lcl_vBuf = BufferUtils.clone(mcl_mesh.getVertexBuffer());
		IntBuffer		lcl_iBuf = BufferUtils.clone(mcl_mesh.getIndexBuffer());

		// do we need to apply world transformations
		if(mcl_worldTXCBox.isSelected()) {
			lcl_vBuf.rewind();
			lcl_iBuf.rewind();

			Quaternion		lcl_r = mcl_mesh.getWorldRotation();
			Vector3f		lcl_sc = mcl_mesh.getWorldScale();
			Vector3f		lcl_tx = mcl_mesh.getWorldTranslation();

			Vector3f		lcl_pta = new Vector3f();

			for(int li_index = 0; li_index < lcl_vBuf.capacity(); li_index += 3) {
				//Utils.out("" + li_index + "vI) " + lcl_vBuf.get());
				lcl_pta.x = lcl_vBuf.get(li_index);
				lcl_pta.y = lcl_vBuf.get(li_index + 1);
				lcl_pta.z = lcl_vBuf.get(li_index + 2);

				lcl_pta.multLocal(lcl_sc);
				lcl_r.mult(lcl_pta, lcl_pta);
				lcl_pta.addLocal(lcl_tx);

				// re-assign
				lcl_vBuf.put(li_index, lcl_pta.x);
				lcl_vBuf.put(li_index + 1, lcl_pta.y);
				lcl_vBuf.put(li_index + 2, lcl_pta.z);

			}

		}

		lcl_vBuf.rewind();

		// do normals
		FloatBuffer		lcl_normalBuf = null;

		if(mcl_normalsCBox != null) {
			if(mcl_normalsCBox.isSelected()) {
				lcl_normalBuf = BufferUtils.clone(mcl_mesh.getNormalBuffer());
			}
		}

		// do colour
		FloatBuffer		lcl_colourBuffer = null;
		if(mcl_coloursCBox != null) {
			if(mcl_coloursCBox.isSelected()) {
				lcl_colourBuffer = BufferUtils.clone(mcl_mesh.getColorBuffer());
			}
		}

		// reconstruct the mesh
		lcl_newTM.reconstruct(lcl_vBuf, 
				lcl_normalBuf, 
				lcl_colourBuffer, 
				null, 
				lcl_iBuf);

		// now do textures
		if(mcl_textureCoordsCBox != null) {
			if(mcl_textureCoordsCBox.isSelected()) {
				lcl_newTM.setTextureCoords(mcl_mesh.getTextureCoords());
			}
		}

		// do the actual save
		if(mcl_saveToLocation.exists()) {
			mcl_saveToLocation.delete();
		}

		try {
			BinaryExporter.getInstance().save(lcl_newTM, mcl_saveToLocation);
		}
		catch (IOException e) {
			e.printStackTrace();
		}
		
		SimpleAlert.doAlert("Trimesh saved.", this);
	}

}
